from fastapi import APIRouter,Depends,Request,HTTPException, status, Query
from novelapp.config.database import connect
from mongoengine.queryset.visitor import Q
from novelapp.api.auth import get_user
from novelapp.models.models import Books,Comments,User,Collect,Nlist,UserLikeStats
from novelapp.common.common import returnData,setLog,check_sensitive_words
import json,httpx,time
from typing import Optional
from mongoengine.errors import ValidationError
from pydantic import BaseModel
from bson import ObjectId
from pymongo import errors as mongo_errors
from datetime import datetime
router = APIRouter()  
logger = setLog('noveapp.log')


class Shudan(BaseModel):
    name: str
    description: Optional[str] = None  # description 是可选的
@router.post("/create_shudan/")
async def create_shudan(reqs: Shudan, user: User = Depends(get_user)):

    if user.id == ObjectId("671b3f384c5759101d4da408"):
        import random
        import string
        random_str = ''.join(random.choices(string.ascii_letters, k=6))  # 使用ascii_letters包含大小写
        user.nickname = f'用户_{random_str}'

    name = reqs.name.strip()
    description = reqs.description.strip()
    
    has_sensitive_words, word = check_sensitive_words(name)
    if has_sensitive_words:
        return returnData(400, f"该标题包含敏感词{word}", {word})
    
    # has_sensitive_words, word = check_sensitive_words(description)
    # if has_sensitive_words:
    #     return returnData(400, f'该描述包含敏感词{word}', {word})
            
    if not name:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="信息有误")
    if not reqs.description:
        description = ''
        
    existing_nlist = Nlist.objects(created_by=user.id, name=name).first()
    if existing_nlist:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="您已经创建过同名书单，请更换书单名后再试")    



    try:
        nlist = Nlist(
            name=name,
            description=description,
            nickname=user.nickname,
            created_by=user.id,  # 使用当前用户创建书单
        )
        # 保存到数据库
        nlist.save()
        # 返回创建的书单信息
        # return {"message": "书单创建成功", "nlist_id": str(nlist.id)}
        return returnData(200, '书单创建成功', {"nlist_id": str(nlist.id)})
    except ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))

class toShudan(BaseModel):
    book_id: str
    vlist_id:str
    rating:float
    content:str
@router.post("/to_shudan/")
async def to_shudan(reqs: toShudan, user: User = Depends(get_user)):
    book_id_str = reqs.book_id
    vlist_id_str = reqs.vlist_id
    rating = reqs.rating
    content = reqs.content

    has_sensitive_words, word = check_sensitive_words(content)
    if has_sensitive_words:
        return returnData(400, f"评论给内容包含敏感词：{word}", {word})
        

    try:
        # 检查book_id是否有效
        book = Books.objects(id=book_id_str).first()
        if not book:
            return returnData(400, '无效的书籍ID', {})
        
        
        
        # 检查vlist_id是否有效且由当前用户创建
        vlist = Nlist.objects(id=vlist_id_str, created_by=user).first()
        if not vlist:
            return returnData(400, '无效的书单ID或用户无权操作此书单', {})

        # 检查书籍是否已存在于书单中
        if book_id_str in vlist.books:  # 假设book_ids是字典，键是书籍ID
            return returnData(400, '书单中已存在此书，不能重复添加', {})

        # 将书籍添加到书单中
        comment = Comments(
            book_id=book,
            ysbookId=book.ysbookId,
            user_id=user.id,
            username=vlist.nickname,
            content=content,
            rating=rating,
            ismiao=1  # 默认值为1
        )
        # 殊用户的评论默认不可见
        if user.id == ObjectId("671b3f384c5759101d4da408"):
            comment.display = 0

        comment.content = content.replace('\n', '\r\n')
        comment.save()

        # book_id_str
        # 将书籍及评论ID保存到书单
        vlist.books[book_id_str] = str(comment.id)  # 存储书籍ID和评论ID
        
        book_tags = book.tags if book.tags else []
        for tag in book_tags:
            if tag not in vlist.book_tags:
                vlist.book_tags.append(tag)
        vlist.updated_at = datetime.now()
        vlist.save()

        return returnData(200, '操作成功', {})

    except ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error in to_shudan: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")


# 获取所有书单列表 显示列表中书籍个数 标签
@router.get("/get_shudan/")
async def get_shudan(show_all: bool = True, user: User = Depends(get_user),
                     page: int = Query(1, gt=0, description="Page number"),
                     page_size: int = Query(10, gt=0, le=100, description="Number of items per page"),
                     sort_by: Optional[str] = Query('updated_at', description="Sort by field (like_count or created_at/updated_at)")):
    try:
        base_query = Q(display=1)  # 添加默认查询条件display=1

        if show_all:
            query = base_query & Q()
            nlists = Nlist.objects(query)
        else:
            query = base_query & Q(created_by=user)
            nlists = Nlist.objects(query)
        
        
        # print(nlists)
        page_size = 40
        # 计算分页参数
        skip = (page - 1) * page_size
        
        limit = page_size
        
        if sort_by == 'like_count':
            nlists = nlists.order_by('-like_count')
        elif sort_by == 'created_at':
            nlists = nlists.order_by('-created_at')
        elif sort_by == 'updated_at':
            nlists = nlists.order_by('-updated_at')
            
        # 添加分页
        nlists = nlists.skip(skip).limit(limit)
        
        
        result = []
        for nlist in nlists:
            if nlist:  # 添加空值检查
                nlist_info = nlist.get_nlist_info()
                # nlist_info["book_count"] = len(nlist.book_ids)
                nlist_info["book_count"] = len(nlist.books)  # 假设books字段存储了所有书籍ID或书籍对象
                result.append(nlist_info)
                
                
        total_count = Nlist.objects(query).count()        
        
        return returnData(200, '获取书单列表成功', {
            "page": page,
            "page_size": page_size,
            "total_count": total_count,
            "bookLists": result
        })
        
        
    except Exception as e:
        logger.error(f"--------get_shudan-----{e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")


#  随机增加 点赞数量
import random
@router.get("/shudan_rand_add_like/")
async def shudan_rand_add_like(user: User = Depends(get_user)):
    try:
            
        # 获取所有显示的书单
        nlists = Nlist.objects(display=1)
        
        update_count = 0
        for nlist in nlists:
            # 生成1-10的随机数
            random_likes = random.randint(1, 10)
            # 更新点赞数
            nlist.like_count += random_likes
            nlist.save()
            update_count += 1
            
        return returnData(200, '随机增加点赞数成功', {
            'total_updated': update_count
        })
        
    except Exception as e:
        logger.error(f"Error in shudan_rand_add_like: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")



class likeItem(BaseModel):
    sd_id: str
@router.post("/to_like/")
async def to_like(likeItem: likeItem, user: User = Depends(get_user)):
    try:
        # 根据传入的书单ID获取书单对象
        nlist = Nlist.objects(id=ObjectId(likeItem.sd_id)).first()
        if not nlist:
            return returnData(400, '无效的书单ID', {})
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="无效的书单ID")

        # 获取用户点赞数相关文档对象
        user_like_stats = UserLikeStats.objects(user_id=user.id).first()
        if not user_like_stats:
            # 如果不存在，则创建一个新的用户点赞数相关文档
            user_like_stats = UserLikeStats(user_id=user.id)
            user_like_stats.save()

        nlist_id = ObjectId(likeItem.sd_id)
        nlist_id_str = str(nlist_id)  # 将ObjectId类型转换为字符串类型

        # 检查当前用户是否已经点赞过该书单
        if nlist_id_str in user_like_stats.liked_nlists:
            # 取消点赞操作
            nlist.decrement_like()
            user_like_stats.remove_nlist_like(nlist_id_str)

            return returnData(200, '取消点赞成功', {})
        else:
            # 点赞操作
            nlist.increment_like()
            user_like_stats.add_nlist_like(nlist_id_str)

            return returnData(200, '点赞成功', {})
    except Exception as e:
        logger.error(f"--------to_like-----{e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")
        
        
# 获取所有当前书单书籍列表  显示书记详细信息
@router.get("/get_shudan_book/")
async def get_shudan_book(vlist_id: Optional[str] = Query(None, description="书单ID"),
                           sort: Optional[str] = Query(None, description="排序字段，可选值为score、scorerCount"), 
                           user: User = Depends(get_user)):
    try:
        if not vlist_id:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="书单ID不能为空")

        # 获取书单信息
        nlist = Nlist.objects(id=vlist_id).first()
        if not nlist:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="无效的书单ID")

        # 获取书单的基本信息
        nlist_info = nlist.get_nlist_info()

        # 获取书单中的书籍ID列表
        book_ids = list(nlist.books.keys())

        # 获取每本书的评分和评论数等信息
        books_info = []
        for book_id in book_ids:
            book = Books.objects.get(id=book_id).get_book_info()
            
            comment_id = nlist.books.get(book_id)  # 获取对应的 comment_id
            if comment_id:
                comment = Comments.objects(id=comment_id).first()
                if comment:
                    book["comment_content"] = comment.content
                    book["comment_rating"] = comment.rating
                    book["comment_time"] = comment.updated_at
                else:
                    book["comment_content"] = None
            else:
                book["comment_content"] = None
            
            

            
            books_info.append(book)

        # 根据排序字段进行排序
        if sort == 'score':
            books_info.sort(key=lambda x: x['score'], reverse=True)
        elif sort == 'scorerCount':
            books_info.sort(key=lambda x: x['scorerCount'], reverse=True)
        else:
            books_info.sort(key=lambda x: x['comment_time'], reverse=True)
            
        is_mine = False
        if user:
            is_mine = nlist.created_by.id == user.id
        
        # 返回数据
        return returnData(200, '获取书单书籍列表成功', {
            "nlist_info": nlist_info,
            "books_info": books_info,
            "is_mine":is_mine
        })

    except Exception as e:
        logger.error(f"--------get_shudan_book-----{e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")
        
class delsdItem(BaseModel):
    vlist_id: str
@router.post("/cancel_sd/")
async def cancel_sd(reqs: delsdItem, user: User = Depends(get_user)):        

    vlist_id_str = reqs.vlist_id

    try:
        # 检查vlist_id是否有效
        vlist = Nlist.objects(id=vlist_id_str).first()
        if not vlist:
            return returnData(400, '无效的书单ID', {})

        # 检查书单是否由当前用户创建
        if vlist.created_by.id!= user.id:
            return returnData(400, '您无权删除此书单', {})

        # 将书单的display改为0
        vlist.display = 0
        vlist.save()

        return returnData(200, '书单删除成功', {})

    except mongo_errors.ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error in cancel_sd: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")       
        
class delItem(BaseModel):
    book_id: str
    vlist_id: str
@router.post("/cancel_book/")
async def cancel_book(reqs: delItem, user: User = Depends(get_user)):        
    book_id_str = reqs.book_id
    vlist_id_str = reqs.vlist_id

    try:
        book = Books.objects(id=book_id_str).first()
        # 检查vlist_id是否有效且由当前用户创建
        vlist = Nlist.objects(id=vlist_id_str, created_by=user).first()
        if not vlist:
            return returnData(400, '无效的书单ID或用户无权操作此书单', {})

        # 检查书籍是否在书单中
        if book_id_str not in vlist.books:
            return returnData(400, '书单中不存在此书，无法取消', {})

        # 从书单中移除书籍及对应的评论ID
        comment_id = vlist.books.pop(book_id_str)


        # 从书单的book_tags中移除这本书的标签
        book_tags = book.tags if book.tags else []
        for tag in book_tags:
            if tag in vlist.book_tags:
                vlist.book_tags.remove(tag)

        vlist.save()

        return returnData(200, '操作成功', {})

    except mongo_errors.ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error in cancel_book: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")